package com.team2.cyber_eye;

import com.team2.cyber_eye.ActivityHelpers.Util;

import android.R.raw;
import android.app.Activity;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.Rect;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;

public class CropView extends View
{
	public CropView(Context context)
	{
		super(context);
		init(null, 0);
	}

	public CropView(Context context, AttributeSet attrs)
	{
		super(context, attrs);
		init(attrs, 0);
	}

	public CropView(Context context, AttributeSet attrs, int defStyle)
	{
		super(context, attrs, defStyle);
		init(attrs, defStyle);
	}

	Bitmap rawImage;
	Bitmap cropImage;
	int rotatePos = 0;
	Rect cropRegion;
	public Activity parent;
	private void init(AttributeSet attrs, int defStyle)
	{
		if (!this.isInEditMode())
		{
			cropImage = null;
			cropRegion = new Rect(20, 20, 200, 200);
			this.setOnTouchListener(new OnTouchListener() { @Override public boolean onTouch(View view, MotionEvent event) { return TouchView(view, event); } });
		}
	}

	Bitmap rotateBitmap(Bitmap bmp, int angle)
	{
		try
		{
			Matrix matrix = new Matrix();
			matrix.postRotate(angle);
			Bitmap newBMP = Bitmap.createBitmap(bmp, 0, 0, bmp.getWidth(), bmp.getHeight(), matrix, true);
			return newBMP;
		}
		catch (OutOfMemoryError ex)
		{
			throw new OutOfMemoryError("Error creating bitmap image for rotation");
		}
	}
	
	public void Rotate()
	{
		rotatePos = (rotatePos+90) % 360;
		
		if (rawImage.getWidth() > 500 || rawImage.getHeight() > 500)
			cropImage = Util.LimitBitmap(rawImage, 500);
		
		if (cropImage.getWidth() > cropImage.getHeight())
			cropImage = rotateBitmap(cropImage, rotatePos);

		this.invalidate();
	}
	
	public void SetImage(Bitmap cropImage)
	{
		rawImage = cropImage;
		
		this.cropImage = cropImage;
		this.invalidate();
	}
	
	boolean move, dragLeft, dragRight, dragTop, dragBottom; 
	int px, py;
	boolean TouchView(View view, MotionEvent event)
	{
		if (event.getAction() == MotionEvent.ACTION_DOWN)
		{
			int x = (int)event.getX();
			int y = (int)event.getY();

			int distance = 30, halfDist = distance / 2;
			Rect largerRect = new Rect(cropRegion.left - halfDist, cropRegion.top - halfDist, cropRegion.right + halfDist, cropRegion.bottom + halfDist);
			Rect smallerRect = new Rect(cropRegion.left + halfDist, cropRegion.top + halfDist, cropRegion.right - halfDist, cropRegion.bottom - halfDist);
			if (largerRect.contains(x, y))
			{
				if (smallerRect.contains(x, y)) 
					move = true;
				else
				{
					if (Math.abs(x - cropRegion.left) < distance) dragLeft = true;
					else if (Math.abs(x - cropRegion.right) < distance) dragRight = true;
					if (Math.abs(y - cropRegion.top) < distance) dragTop = true;
					else if (Math.abs(y - cropRegion.bottom) < distance) dragBottom = true;
				}
			}
			px = x;
			py = y;
			
			return true;
		}
		else if (event.getAction() == MotionEvent.ACTION_MOVE)
		{
			int x = (int)event.getX();
			int y = (int)event.getY();
			
			if (dragLeft) cropRegion.left += x - px;
			else if (dragRight) cropRegion.right += x - px;
			if (dragTop) cropRegion.top += y - py;
			else if (dragBottom) cropRegion.bottom += y - py;
			
			if (move) cropRegion.offset(x-px, y-py);

			if (cropRegion.height() > screenRect.height()) { cropRegion.top = screenRect.top; cropRegion.bottom = screenRect.bottom; }
			if (cropRegion.width() > screenRect.width()) { cropRegion.left = screenRect.left; cropRegion.right = screenRect.right; }
			if (cropRegion.left < 0) cropRegion.offset(-cropRegion.left, 0);
			if (cropRegion.top < 0) cropRegion.offset(0, -cropRegion.top);
			if (cropRegion.right > screenRect.right) cropRegion.offset(screenRect.right-cropRegion.right, 0);
			if (cropRegion.bottom > screenRect.bottom) cropRegion.offset(0, screenRect.bottom-cropRegion.bottom);
			
			this.invalidate();
				
			px = x;
			py = y;
			
			return true;
		}
		else if (event.getAction() == MotionEvent.ACTION_UP)
		{
			move = false;
			dragLeft = false;
			dragRight = false;
			dragTop = false;
			dragBottom = false;
			
			return false;
		}
		else
		{
			px = (int)event.getX();
			py = (int)event.getY();
			
			return false;
		}
	}
	
	
	Rect bmpRect = new Rect(0, 0, 0, 0);
	Rect screenRect = new Rect(0, 0, 0, 0);
    Paint p1 = new Paint();
    Paint p2 = new Paint();
    @Override
    protected void onDraw(Canvas canvas)
    {
        super.onDraw(canvas);
        
		if (this.isInEditMode())
		{
			p1.setColor(getResources().getColor(R.color.green));
			p1.setStrokeWidth(5);
	        canvas.drawLine(0, 0, this.getWidth(), this.getHeight(), p1);
	        canvas.drawLine(this.getWidth(), 0, 0, this.getHeight(), p1);
        }
		else if (cropImage != null)
		{
			//if (canvas.getWidth() != this.getWidth() || canvas.getHeight() != this.getHeight())
			//	return;
			bmpRect.right = cropImage.getWidth();
			bmpRect.bottom = cropImage.getHeight();
			//canvas.getClipBounds(screenRect);
			screenRect.left = 0;
			screenRect.top = 0;
			screenRect.right = this.getWidth();
			screenRect.bottom = this.getHeight();
			
			canvas.drawBitmap(cropImage, bmpRect, screenRect, p1);
			
			p1.setColor(getResources().getColor(R.color.green));

			if (move)
				p1.setColor(getResources().getColor(R.color.red));
			p2.setColor(getResources().getColor(R.color.red));
	        p2.setStrokeWidth(7);
			
	        p1.setStrokeWidth(3);
	        
			if (dragLeft) canvas.drawLine(cropRegion.left, cropRegion.top, cropRegion.left, cropRegion.bottom, p2);
			else canvas.drawLine(cropRegion.left, cropRegion.top, cropRegion.left, cropRegion.bottom, p1);
			
			if (dragTop) canvas.drawLine(cropRegion.left, cropRegion.top, cropRegion.right, cropRegion.top, p2);
			else canvas.drawLine(cropRegion.left, cropRegion.top, cropRegion.right, cropRegion.top, p1);

			if (dragRight) canvas.drawLine(cropRegion.right, cropRegion.top, cropRegion.right, cropRegion.bottom, p2);
			else canvas.drawLine(cropRegion.right, cropRegion.top, cropRegion.right, cropRegion.bottom, p1);
	        
			if (dragBottom) canvas.drawLine(cropRegion.left, cropRegion.bottom, cropRegion.right, cropRegion.bottom, p2);
			else canvas.drawLine(cropRegion.left, cropRegion.bottom, cropRegion.right, cropRegion.bottom, p1);
		}
    }
    
    public Bitmap GetClipRegion()
    {
    	int x,y,w,h;
    	float scaleX = (float)rawImage.getWidth() / (float)this.getWidth();
    	float scaleY = (float)rawImage.getHeight() / (float)this.getHeight();
    	float aspect = (float)this.getWidth() / (float)this.getHeight();
    	
    	Bitmap bmp = null;
    	try
    	{
    		if (rotatePos == 0)
    		{
    	    	x = (int)Math.round(cropRegion.left * scaleX);
    	    	y = (int)Math.round(cropRegion.top * scaleY);
    	    	w = (int)Math.round(cropRegion.width() * scaleX);
    	    	h = (int)Math.round(cropRegion.height() * scaleY);
    		}
    		else if (rotatePos == 90)
    		{
    			x = (int)Math.round((cropRegion.top * aspect) * scaleX);
    	    	y = (int)Math.round(((this.getWidth() - cropRegion.right) / aspect) * scaleY);
    	    	w = (int)Math.round((cropRegion.height() * aspect) * scaleX);
    	    	h = (int)Math.round((cropRegion.width() / aspect) * scaleY);
    		}
    		else if (rotatePos == 180)
    		{
    	    	x = (int)Math.round((this.getWidth() - cropRegion.right) * scaleX);
    	    	y = (int)Math.round((this.getHeight() - cropRegion.bottom) * scaleY);
    	    	w = (int)Math.round(cropRegion.width() * scaleX);
    	    	h = (int)Math.round(cropRegion.height() * scaleY);
    		}
    		else //if (rotatePos == 270)
    		{
    			x = (int)Math.round(((this.getHeight() - cropRegion.bottom) * aspect) * scaleX);
    	    	y = (int)Math.round((cropRegion.left / aspect) * scaleY);
    	    	w = (int)Math.round((cropRegion.height() * aspect) * scaleX);
    	    	h = (int)Math.round((cropRegion.width() / aspect) * scaleY);
    		}
    		
        	if (x < 0) x = 0;
        	if (y < 0) y = 0;
        	if (x+w > rawImage.getWidth()) w = rawImage.getWidth()-x;
        	if (y+h > rawImage.getHeight()) h = rawImage.getHeight()-y;
        	cropImage = rawImage;
        	
        	rawImage = Bitmap.createBitmap(rawImage, x, y, w, h);
    	}
    	catch(Exception ex)
    	{
    		Util.DisplayError(this.getContext(), "Error creating new cropped image", ex);
		}
    	catch(OutOfMemoryError ex)
    	{
    		Util.DisplayIssue(this.getContext(), "Out of memory error for cropped image");
		}
    	
    	return rawImage;
    }
}
